package fr.jade.fraclite.factory;

import java.io.PrintStream;
import java.io.PrintWriter;

import org.objectweb.fractal.api.factory.InstantiationException;

/**
 * A sub class of the {@link InstantiationException} class.
 */

public class ChainedInstantiationException extends InstantiationException {

  /**
   * The exception that caused this exception. May be <tt>null</tt>.
   */

  private final Throwable exception;


  /**
   * Constructs a new {@link ChainedInstantiationException} exception.
   *
   * @param exception the cause of this exception. May be <tt>null</tt>.
   * @param factory the factory component that cannot be instantiated. May be
   *      <tt>null</tt>.
   * @param message a detailed error message.
   */

  public ChainedInstantiationException (Throwable exception, String message) {
    super(message);
    this.exception = exception;
  }

  /**
   * Returns the exception that caused in this exception.
   *
   * @return the exception that caused this exception. May be <tt>null</tt>.
   */

  public Throwable getException () {
    return exception;
  }


  // -------------------------------------------------------------------------
  // Overriden Exception methods
  // -------------------------------------------------------------------------

  /**
   * Returns a String representation of this exception.
   *
   * @return a String representation of this exception.
   */

  public String toString () {
    StringBuffer buf = new StringBuffer();
    buf.append("InstantiationException: ");
    buf.append(getMessage());
    return buf.toString();
  }

  /**
   * Prints the stack backtrace.
   */

  public void printStackTrace () {
    if (exception != null) {
      System.err.println(this);
      exception.printStackTrace();
    } else {
      super.printStackTrace();
    }
  }

  /**
   * Prints this exception and its backtrace to the specified print stream.
   *
   * @param s <tt>PrintStream</tt> to use for output.
   */

  public void printStackTrace (final PrintStream s) {
    if (exception != null) {
      s.println(this);
      exception.printStackTrace(s);
    } else {
      super.printStackTrace(s);
    }
  }

  /**
   * Prints this exception and its backtrace to the specified print writer.
   *
   * @param s <tt>PrintWriter</tt> to use for output.
   */

  public void printStackTrace (final PrintWriter s) {
    if (exception != null) {
      s.write(this + "\n");
      exception.printStackTrace(s);
    } else {
      super.printStackTrace(s);
    }
  }
  
}
